KISS User Manual for C


Introduction

KIPR's Instructional Software System (KISS for short) is an integrated development environment providing an editor, compilers for multiple programming languages, and a set of libraries and simulator for the LINK Botball Controller. KISS implements the full ANSI C specification. For information about the C programing language, including history and basic syntax, see the Wikipedia article C (programming language). For a more complete tutorial and guide for C Programming visit CPrograming. The Botball community website also has several articles about programming and a user forum where questions can be posted to the botball community. For specific information on Motors and Sensors, see the Sensors and Motors Manual

The primary purpose of this manual is to describe the KIPR Link Botball Controller libraries and simulator, which are extensions to the C programming language. This file also provides a basic introduction to programming in C. To learn more about programming in C, consult one of the many books or websites that provide C references and tutorials.

KISS Interface

Both new (unsaved) and saved files can be opened for editing in KISS. A row of tabs lists the files that have been opened. Clicking a file's tab activates it for editing.

The File menu has standard entries for New, Open, Save, Save As, Print, Close and Exit.

To use the simulator, simply select Simulator as the target for KISS. Clicking Compile will compile and run the program in the simulator. The active file will also be saved, unless it is new, in which case the user is prompted for a "save as" file name. The active file must contain (or #include) the main function in order to run in the simulator.

When your Link is cabled to your computer, its name will appear as one of the available targets. Now clicking Compile will compile and download your program to your Link, where it can be run from the Link's Programs tab.

The interface provides additional capabilities for program entry/edit, minor adjustment to the display (font size), auto-completion and auto-indentation. If there is a syntax error in the program, an error window will appear at the bottom of the KISS screen with the error message and the file and line number where the error was detected. If the error occurred in the active file, then clicking on the error message will move to that line. The edit menu provides a Go To line option.

C programs are automatically formatted and indented. Keywords, comments, and text strings are highlighted with color unless this feature is turned off. Most Link-specific library functions will have pop-help when they are entered into the input window.

KISS does parenthesis-balance-highlighting when the cursor is placed to the right of any right parenthesis, bracket, or brace.

A Quick C Tutorial

Most C programs consist of function definitions and data structures. Here is a simple C program that defines a single function, called main.

/* Simple example: C Programmer's Manual */

int main()
{
    printf("Hello, world!/n");// simple example
}

For a C program to be executable, one of its functions must be named main.

The Expression

/* <text> */

forms a multi-line or bracketed comment. In contrast, text that starts with

//

forms a single line comment, which continues only to the end of the line. Comments are ignored by C when the program is compiled.

All functions must have a return type. While main does not return a value to another function, it does return an integer to the operating system, and so is of type int. Other types include no return value (void) and floating point numbers are best specified by using (double). This function declaration information must precede each function definition.

Immediately following the function declaration is the function's name (in this case,main). Next, in parentheses, are any arguments (or inputs) to the function. main has none, but an empty set of parentheses is still required.

After the function arguments is an open curly-brace {. This signifies the start of the actual function code. Curly-braces signify program blocks, or chunks of code.

Next comes a series of C statements. Statements demand that some action be taken. Our demonstration program has a single statement, a printf ("Hello, world!/n"). This will print the message "Hello, world!" to the KIPR Link display. The \n indicates start-of-a-new-line (in effect ending the current line and positioning for the next print to start on the next line). When the bottom of the display is reached, additional lines cause the display to scroll up. The printf statement ends with a semicolon (;). All C statements must be ended by a semicolon. Beginning C programmers commonly make the error of omitting the semicolon that is required to end each statement.

The main function is ended by the close curly-brace }.

Let's look at another example to learn some more features of C. The following code defines the function square, which returns the mathematical square of a number.

int square(int n)
{
    return(n * n);
}

The function is declared as type int, which means that it will return an integer value.

Next comes the function named square, followed by its argument list in parentheses. Square has one argument, n, which is an integer. Notice how declaring the type of the argument is done similarly to declaring the type of the function.

When a function has arguments declared, those argument variables are valid within the "scope" of the function (i.e., they only have meaning within the function's own code). Other functions may use the same variable names independently.

The code, or "scope", for square is contained within the set of curly braces. In fact, it consists of a single statement: the return statement. The return statement exits the function and returns the value of the C expression that follows it (in this case "n * n").

Except where grouped by parentheses, expressions are evaluated according to a set of precedence rules associated with the various operations within the expression. In this case, there is only one operation (multiplication), signified by the "*", so precedence is not an issue.

Let's look at an example of a function that performs a function call to the square program.

double hypotenuse(int a, int b)
{
    double h;
    h = sqrt((double)(square(a) + square(b)));
    return(h);
}

This code demonstrates several more features of C. First, notice that the floating point variable h is defined at the beginning of the hypotenuse function. In general, whenever a new program block (indicated by a set of curly braces) is begun, new local variables may be defined.

The value of h is set to the result of a call to the sqrt function, which is included from the C math library by KISS. sqrt is a built-in C function that takes a floating point number as its argument.

We want to use the square function we defined earlier, which returns its result as an integer. But the sqrt function requires a floating point argument. We get around this type incompatibility by coercing the integer sum (square(a) + square(b)) into a float by preceding it with the desired type, in parentheses. Thus, the integer sum is made into a floating point number and passed along to sqrt.

The hypotenuse function finishes by returning the value of h.

Note that the functions square and hypotenuse are functions, not a program. If they are in the same file as the main function written above, they will never be called. If main was modified to be:

/* Simple example: C Programmer's Manual */

int main()
{
    printf("Hypotenuse of 3,4 is %d\n",hypotenuse(3,4)); // call a function
}

then the program (which always starts execution with main) would calculate and print out the hypotenuse of a triangle with side lengths of 3 & 4. However, C requires that functions be defined before they are first called. Since hypotenuse is called in main, either the functions need to be defined earlier in the file, or they can be prototyped at the begining of the file. A prototype of a C function is simply a C statement that includes the return type, function name and types of the parameters. For example the prototypes of the functions square and hypotenuse would be:

int square(int n);
double hypotenuse(int a, int b);

The order in which function protypes appear does not matter as long as they come before the definitions that call that function.

This concludes the brief C tutorial.

Data Objects

Variables and constants are the basic data objects in a C program. Declarations list the variables to be used, state what type they are, and may set their initial value.

Variables

Variable names are case-sensitive. The underscore character is allowed and is often used to enhance the readability of long variable names. C keywords like if, while, etc. may not be used as variable names.

Functions and global variables may not have the same name. In addition, if a local variable is named the same as a function or a global variable, the local use takes precedence; ie., use of the function or global variable is prevented within the scope of the local variable.

Declaration

In C, variables can be declared at the top level (outside of any curly braces) or at the start of each block (a functional unit of code surrounded by curly braces). In general, a variable declaration is of the form:

<type>  <variable-name>; or
<type>  <variable-name>=<initialization-data>;

In C, <type> can be int, double, char, or struct <struct-name>, and determines the primary type of the variable declared. This form changes somewhat when dealing with pointer and array declarations, which are explained in a later section, but in general this is the way you declare variables.

Local and Global Scopes

If a variable is declared within a function, or as an argument to a function, its binding is local, meaning that the variable has existence only within that function definition. If a variable is declared outside of a function, it is a global variable. It is defined for all functions, including functions which are defined in files other than the one in which the global variable was declared.

Variable Initialization

Local and global variables can be initialized to a value when they are declared. If no initialization value is given, their value is indeterminate.

All global variable declarations must be initialized to constant values. Local variables may be initialized to the value of arbitrary expressions including any global variables, function calls, function arguments, or local variables which have already been initialized.

Here is a small example of how initialized declarations are used.

int i=50; /* declare i as global integer; initial value 50 */
double j=100.123; /* declare j as global double; initial value 100.123 */
int foo()
{
    int x; /* declare x as local integer; initial value 0 */
    double y=j; /* declare y as local double; initial value j */
}

Local variables are initialized whenever the function containing them is executed. Global variables are initialized whenever a reset condition occurs. Reset conditions occur when:

  1. Code is downloaded;
  2. The main() procedure is run;
  3. System hardware reset occurs

Constants

Integer Constants

Integers constants may be defined in decimal integer format (e.g., 4053 or -1) or hexadecimal format using the "0x" prefix (e.g., 0x1fffffff).

Floating Point constants

Floating point numbers may use exponential notation (e.g., "10e3" or "10E3") or may contain a decimal period. For example, the floating point zero can be given as "0.", "0.0", or "0E1", but not as just "0". Since the board has no floating point hardware, floating point operations are handled by software, making them much slower than integer operations. Hence,floating point should only be used for data that is inherently fractional.

Characters and String Constants

Quoted characters return their ASCII value (e.g., 'x').

Character string constants are defined with quotation marks, e.g., "This is a character string.".

NULL

The special constant NULL can be assigned to and compared to pointer or array variables (which will be described in later sections). In general, a pointer represents a memory location. A NULL pointer represents the case the pointer points to nothing.

To check if a pointer variable has been been assigned you compare its value to NULL. As an example, if you had a defined a linked list type consisting of a value and a pointer to the next element, the end of the list is determined by comparing a list element's pointer variable to NULL.

Data Types

C supports the following data types among others:

32-bit Integers

32-bit integers are signified by the type indicator int. They are signed integers, and may be valued from -2,147,483,648 to +2,147,483,647 decimal.

64-bit Floating Point Numbers

Floating point numbers are best specif by the type indicator double. 64-bit floating point numbers have at least 15 decimal digits of precision and are valued from about 10^-308 to 10^308.

8-bit Characters

Characters are an 8-bit (unsigned) number signified by the type indicator char. A character's value normally represents a standard ASCII character code, most of which are printable.

Pointers

C pointers are 32-bit numbers which represent locations in memory. Values in memory can be manipulated by calculating, passing and dereferencing pointers representing the location where the information is stored (derefence means to obtain the value stored at the location).

Arrays

Arrays are used to store homogenous lists of data (meaning that all the elements of an array have the same type). Every array has a length which is determined at the time the array is declared. The data stored in the elements of an array can be set and retrieved in the same manner as for other variables.

Structures

Structures are used to store non-homogenous but related sets of data. Elements of a structure are referenced by name instead of number and may be of any supported type.

Structures are useful for organizing related data into a coherent format, reducing the number of arguments passed to functions, increasing the effective number of values which can be returned by functions, and creating complex data representations such as directed graphs and linked lists.

Pointers

The address where a value is stored in memory is known as the pointer to that value. It is often useful to deal with pointers to objects, but great care must be taken to insure that the pointers used at any point in your code really do point to valid objects in memory.

For additional information on programming with C pointers, please refer to a C programming book or website.

Arrays

C supports arrays of characters, integers, floating-point numbers, structures, pointers, and array pointers (multi-dimensional arrays). The main reasons that arrays are useful are that they allow you to allocate space for many instances of a given type, send an arbitrary number of values to functions, and provide the means for iterating over a set of values.

Declaring and Initializing Arrays

Arrays are declared using square brackets. The following statement declares an array of ten integers:

int foo[10];

this array, elements are numbered from 0 to 9. Elements are accessed by enclosing the index number within square brackets: foo[4] denotes the fifth element of the array foo (since counting begins at zero).

Arrays not initialized at declaration contain indeterminate values. Arrays may be initialized at declaration by specifying the array elements, separated by commas, within curly braces. If no size value is specified within the square brackets when the array is declared but initialization information is given, the size of the array is determined by the number of elements given in the declaration. For example,

int foo[]= {0, 4, 5, -8,  17, 301};

creates an array of six integers, with foo[0] equaling 0, foo[1] equaling 4, etc.

If a size is specified and initialization data is given, the length of the initialization data may not exceed the specified length of the array or an error results. If, on the other hand, you specify the size and provide fewer initialization elements than the total length of the array, the remaining elements contain indeterminate values.

Text strings are implemented as arrays of characters. C provides a syntax for initializing arrays of characters. The character values of the string are enclosed in quotation marks as given in the following example:

char ex_string[]= "Hello there";

This initializes the character array ex_string with the ASCII values of the specified characters. The length of the array is the number of characters in the string plus 1, since strings are automatically terminated by the (unprintable) ASCII character '\0'. The terminator is the means C uses to view the array as a string. C has a library of string functions included by KISS for determining string length, combining strings, and the like (look for string functions in your C reference).

A character array can be initialized using the curly braces syntax, but unless '\0' is included, there is nothing to mark the end of the string, and printing the array as a string will produce indeterminate results. In declaring a character array intended to hold strings, the array size needs to be 1 larger than the size of the maximum string to allow for '\0'. For example, given

char pg_string[81];

strings of length up to 80 can be stored in the variable pg_string

Passing Arrays as Arguments

When an array is passed to a function as an argument, the array's pointer is actually passed, rather than the elements of the array. If the function modifies the array values, the array will be modified, since there is only one copy of the array in memory.

There are two ways of declaring an array argument: as an array or as a pointer to the type of the array's elements.

As an example, the following function takes an index and an array, and returns the array element specified by the index:

int retrieve_element(int index, int array[])
{
    return array[index];
}

Notice the use of the square brackets to declare the argument array as a pointer to an array of integers.

When passing an array variable to a function, you are actually passing the value of the array pointer itself and not one of its elements, so no square brackets are used.

void foo()
{
    int array[10];
    retrieve_element(3, array);
}

Multi-dimensional Arrays

A two-dimensional array is just like a single dimensional array whose elements are one-dimensional arrays. Declaration of a two-dimensional array is as follows:

int k[2][3];

The number in the first set of brackets is the number of 1-D arrays of int. The number in the second set of brackets is the length of each of the 1-D arrays of int. In this example, k is an array containing two 1-D arrays; each of k[0] and k[1] is a 1-D array of length 3 consisting of values of type int. k[0][1] is the value in position 1 of k[0]. Arrays of with any number of dimensions can be generalized from this example by adding more brackets in the declaration.

Structures

Structures are used to store non-homogenous but related sets of data. Elements of a structure are referenced by name instead of number and may be of any supported type. Structures are useful for organizing related data into a coherent format, reducing the number of arguments passed to functions, increasing the effective number of values which can be returned by functions, and creating complex data representations such as directed graphs and linked lists.

The following example shows how to define a structure, declare a variable of structure type, and access its elements.

struct foo
{
    int i;
    int j;
};
struct foo f1;
void set_f1(int i,int j)
{
    f1.i=i;
    f1.j=j;
}
void get_f1(int *i,int *j)
{
    *i=f1.i;
    *j=f1.j;
}

The first part is the structure definition. It consists of the keyword struct, followed by the name of the structure (which can be any valid identifier), followed by a list of named elements in curly braces. This definition specifies the structure of the type struct foo. Once there is a definition of this form, you can use the type struct foo just like any other type. The line

struct foo f1;

is a global variable declaration which declares the variable f1 to be of type struct foo.

The dot operator is used to access the elements of a variable of structure type. In this case, f1.i and f1.j refer to the two elements of the struct variable f1. You can treat the quantities f1.i and f1.j just as you would treat any variables of type int (the type of the elements specified in the struct declaration of foo is int).

Pointers to structure types can also be used, just like pointers to any other type. However, with structures, there is a special short-cut for referring to the elements of the structure pointed to.

struct foo *fptr;
void main()
{
    fptr=&f1;
    fptr->i=10;
    fptr->j=20;
}

this example, fptr is declared to be a pointer to type struct foo. In main, it is set to point to the global f1 defined above. Then the elements of the structure pointed to by fptr (in this case these are the same as the elements of f1), are set. The arrow operator is used instead of the dot operator because fptr is a pointer to a variable of type struct foo. Note that (*fptr).i would have worked just as well as fptr->i, but it would have been clumsier.

Note that just as for arrays, only pointers to structures, not the structures themselves, can be passed to or returned from functions.

Complex Initialization examples

Complex types -- arrays and structures -- may be initialized upon declaration with a sequence of constant values contained within curly braces and separated by commas.

Arrays of character may also be initialized as a string using a quoted string of characters.

For initialized declarations of single dimensional arrays, the length can be left blank and a suitable length based on the initialization data will be assigned to it. Multi-dimensional arrays must have the size of all dimensions specified when the array is declared. If a length is specified, the initialization data may not overflow that length in any dimension or an error will result. However, the initialization data may be shorter than the specified size and the remaining entries will be initialized to 0.

Following is an example of legal global and local variable initializations:

/* declare many globals of various types */
int i=50;
int *ptr=NULL;
double farr[3]={ 1.2, 3.6, 7.4 };
int tarr[2][4]={ { 1, 2, 3, 4 }, { 2, 4, 6, 8} };
char c[]="Hi there how are you?";
char carr[5][10]={"Hi","there","how","are","you"};
struct bar
{
    int i;
    int *p;
    double j;
} b={5, NULL, 10.5};
struct bar barr[2] = { { 1, NULL, 2.5 }, { 3 } };
/* declare locals of various types */
int foo()
{
    int x; /* local variable x with initial value 0 */
    int y= tarr[0][2]; /* local variable y with initial value 3 */
    int *iptr=&i; /* local pointer to integer
                                which points to the global i */
    int larr[2]={10,20};  /* local array larr
                                   with elements 10 and 20 */
    struct bar lb={5,NULL,10.5}; /* local variable of type
                                          struct bar with i=5 and j=10.5 */
    char lc[]=carr[2];    /* local string lc with
                                   initial value "how" */
    ...
}

Statements and Expressions

Operators act upon objects of a certain type or types and specify what is to be done to them. Expressions combine variables and constants to create new values. Statements are expressions, assignments, function calls, or control flow statements which make up C programs.

Operators

Each of the data types has its own set of operators that determine which operations may be performed on them.

Integer Operations

The following operations are supported on integers:

Floating Point Numbers

KISS provides the standard C library of floating point routines. This package includes arithmetic, trigonometric, and logarithmic functions. Since floating point operations are implemented in software, they are much slower than the integer operations and so should be avoided where possible if your programming objective could be affected by overall processing speed.

The following operations are supported on floating point numbers:

  • Arithmetic. addition +, subtraction -, multiplication *, division /.
  • Comparison. greater-than >, less-than <, equality ==, greater-than-equal >=, less-than-equal <=.
  • Built-in Math Functions. A set of trigonometric, logarithmic, and exponential functions is supported. For details, go to the Library Function Descriptions. These functions are included among those itemized as "Math" functions.

Characters

Character variables hold 8-bit unsigned integers whose values reference standard ASCII codes. If a character variable is referenced in an integer operation, it is automatically coerced into an integer representation for use by the integer operation. When a value is stored into a character variable, it is coerced into an 8-bit character (by truncating the upper bits).

Assignment Operators and Expressions

The basic assignment operator is =. The following statement adds 2 to the value of a.

a = a + 2;

The abbreviated form

a += 2;

could also be used to perform the same operation. All of the following binary operators can be used in this fashion:

+   -   *   /   %   <<   >>   &   ^   |

Increment and Decrement Operators

The increment operator "++" increments the named variable. For example, the construction "a++" is equivalent to " a= a+1" or "a+= 1". A statement that uses an increment operator has a value. For example, the statement

a = 3; printf("a=%d a+1=%d\n", a, ++a);

will display the text "a=3 a+1=4". If the increment operator comes after the named variable, then the value of the statement is calculated after the increment occurs. So the statement

a = 3; printf("a=%d a+1=%d\n", a, a++);

would display "a=3 a+1=3" but would finish with a set to 4. The decrement operator "--" is used in the same fashion as the increment operator.

Data Access Operators

&
 
A single ampersand preceding a variable, an array reference, or a structure element reference returns a pointer to the location in memory where that information is being stored. This should not be used on arbitrary expressions as they do not have a stable place in memory where they are being stored.
*
 
A single * preceeding an expression which evaluates to a pointer returns the value which is stored at that address. This process of accessing the value stored within a pointer is known as dereferencing.
[<expr>]
 
An expression in square braces following an expression which evaluates to an array (an array variable, the result of a function which returns an array pointer, etc.) checks that the value of the expression falls within the bounds of the array and references that element.
.
 
A dot between a structure variable and the name of one of its fields returns the value stored in that field.
->
 
An arrow between a pointer to a structure and the name of one of its fields in that structure acts the same as a dot does, except it acts on the structure pointed at by its left hand side. Where f is a structure of a type with i as an element name, the two expressions f.i and (&f)->i are equivalent.

Precedence and Order of Evaluation

The following table summarizes the rules for precedence and associativity for the C operators. Operators listed earlier in the table have higher precedence; operators on the same line of the table have equal precedence.

Operator   Associativity  
  () [] left to right
  ! ~ ++ -- - (<type>)   right to left
  * / % left to right
  + - left to right
  << >> left to right
  < <= > >= left to right
  == != left to right
  & left to right
  ^ left to right
  | left to right
  && left to right
  || right to left
  = += -= etc. right to left
  , left to right

Control Flow

All standard C control structures are available under KISS.

Statements and Blocks

A single C statement is ended by a semicolon. A series of statements may be grouped together into a block using curly braces. Inside a block, local variables may be defined. Blocks may be used in place of statements in the control flow constructs.

For the following, keep in mind a <block> can be used instead of the <statement>.

If-Else

The if else statement is used to make decisions. The syntax is:

if (<expression>)
    <statement-1>
else
    <statement-1>

<expression> is evaluated; if it is not equal to zero (e.g., logic true), then <statement-1> is executed.

The else clause is optional. If the if part of the statement did not execute, and the else is present, then <statement-2> executes.

While

The syntax of a while loop is the following:

while (<expression>)
    <statement>

while begins by evaluating <expression>. If it is false, then <statement> is skipped. If it is true, then <statement> is evaluated. Then the expression is evaluated again, and the same check is performed. The loop exits when <expression> becomes zero.

One can easily create an infinite loop in C using the while statement:

while (1)
    <statement>

Do-While

The syntax of a do-while loop is the following:

do
    <statement>
while (<expression>);

The equivalent while loop would be the following:

<statement>
while (<expression>)
    <statement>

For

The syntax of a for loop is the following:

for (<expr-1>;<expr-2>;<expr-3>)
    <statement>

The for construct is equivalent to the following construct using while:

<expr-1>;
while (<expr-2>)
{
    <statement>
    <expr-3>;
}

Typically, <expr-1> is an assignment, <expr-2> is a relational expression, and <expr-3> is an increment or decrement of some manner. For example, the following code counts from 0 to 99, printing each number along the way:

int i;
for (i = 0; i < 100; i++)
    printf("%d\n", i);

Switch

The syntax of a switch block is as follows:

switch (int)
{
    case const1:
        <statement list1>
    break;
    case const2:
        <statement list2>
    break;
    default:
        <statement list3>
}

The switch construct takes an integer variable as input, and compares it to each case listed. The first matching const is selected, and execution begins there. The break is optional, and if no break is found then execution continues through each following statement. Also note that each case has a list of single statements, as opposed to a block enclosed in curly braces.

Here's an example of how a switch might be used:

int i = 1;
switch(i)
{
    case 0:
        printf("Case 0\n");
        break;
    case 1:
        printf("Case 1\n");
        break;
    default:
        printf("Default\n");
}

Since i is equal to 1, the text "Case 1" will be printed to the screen. If i were equal to 0, "Case 0" would be printed. If i were any number besides 0 or 1, "Default" would be printed.

Break

Use of the break statement provides an early exit from a while, do-while or for loop. The break statement can also provide an exit from a switch block.

Display Screen Printing

The C function printf provides formatted printing to the KIPR Link display screen. KISS also provides a Link specific print command, display_printf, for controlled screen printing to at a specified (row,column) coordinate on the 10 line by 42 character display (3 button mode only).

The syntax of printf is the following:

printf(<format-string>, <arg-1> , ... , <arg-N>);

This is best illustrated by some examples.

Printing Examples

Example 1: Printing a message

The following statement prints a text string to the screen.

printf("Hello, world!\n");

In this example, the format string is simply printed to the screen. The character \n at the end of the string signifies an advance to the next (or new) line for subsequent printing. When the bottom of the display is reached, the display is scrolled (up) for each line subsequently printed.

Example 2: Printing a number

The following example prints the value of the integer variable x with a brief message.

printf("Value is %d\n", x);

The format %d phrase signals that the first variable in the list is to be formatted as and integer, replacing %d in the printed output.

Example 3: Printing a number in hexadecimal

The following example prints the value of the integer variable x as a hexadecimal number (in caps).

printf("Value is %X\n", x);

The format %X phrase signals that the first variable in the list is to be formatted as hexadecimal value (using uppercase), replacing %X in the printed output.

Example 4: Printing a floating point number

The following statement prints the value of the floating point variable n as a floating point number.

printf("Value is %f\n", n);

The format %f phrase signals that the first variable in the list is to be formatted as a decimal floating point value (with decimal point), replacing %f in the printed output.

Example 5: Printing two numbers in hexadecimal format (lower case)

printf("A=%x  B=%x\n", a, b);

The first %x applies to variable a and the second to variable b.

Example 6: Printing using display_printf

display_printf(0,2,"A=%d  B=%d", a, b);

The function display_printf is like the standard printf function except the first two arguments specify the column and row (zero indexed) to start printing, so for this example, the result is printed on the 3rd row of the display starting from column 0.

Row numbers are 0 to 9, column 0 to 41. Note that display_printf does not wrap, and truncates strings that go beyond the end of the line on the display.

Formatting Command Summary

 Format Command  Data Type Description
  %d   int   decimal number
  %x or %X   int   hexadecimal number
  %c   int   low byte as ASCII character  
  %f   double   floating point number
  %s   char array     char array (string)

Preprocessor

The preprocessor processes a file before it is sent to the compiler. The C preprocessor allows definition of macros, and conditional compilation of sections of code. Using preprocessor macros for constants and function macros can make C code more efficient as well as easier to read. Using #if to conditionally compile code can be very useful, for instance, for debugging purposes.

The preprocessor command #include causes the specified file to be included in the code sent to the C compiler at the position the include statement appears in the program. For example, suppose you have a set of stored programs in a file named "mylib.c", some of which you need for your current program to work.

// load my library 
#include "mylib.c"

void main()
{
    char s[32] = "text string wrapping badly\n";
    fix(s);// apply my fix function to s and print it 
    printf(s);
}

Preprocessor Macros

Preprocessor macros are defined by using the #define preprocessor directive at the beginning of a line. The macro will apply to any other files subsequently included in the program. The following example shows how to define preprocessor macros.

#define RIGHT_MOTOR 0
#define LEFT_MOTOR  1
#define GO_RIGHT(power) (motor(RIGHT_MOTOR,(power)))
#define GO_LEFT(power)  (motor(LEFT_MOTOR,(power)))
#define GO(left,right) {GO_LEFT(left); GO_RIGHT(right);}
void main()
{
    GO(0,0);
}

Preprocessor macro definitions start with the #define directive at the beginning of a line, and continue to the end of the line. The name of the macro follows #define, such as RIGHT_MOTOR (a C programming convention is to use all caps for macro names to make them easy to identify later). If there is a parenthesis directly after the name of the macro, such as the GO_RIGHT macro has above, then the macro has arguments. The GO_RIGHT and GO_LEFT macros each take one argument. The GO macro takes two arguments. The body of the macro follows the name and the optional argument list.

Each time a macro is invoked, any variables are resolved in the body of the macro and the code produced is placed in the program in place of the macro.

Superficially, invocations of macros without arguments look like global variable references and invocations of macros with arguments look like calls to functions. However, macro replacement is occurs as the preprocessor passes through the program before sending it on to the compiler. Global references and function calls happen after compilation at run time. Also, function calls actually evaluate their arguments before they are called, whereas macros simply perform text replacement.

Appropriate use of macros can make C programs easier to read. In particular, constants can be given symbolic names rather than using global variables to provide storage for them. It also allows macros with arguments to be used in cases when a series of function calls is used at multiple points in the program.

Conditional compilation

It is sometimes desirable to conditionally compile code. The primary example of this is that you may want to have easily supressed debugging output. The C preprocessor provides a convenient way of doing this by using the #ifdef directive.

void go_left(int power)
{
    GO_LEFT(power);
    #ifdef DEBUG
    printf("Going Left\n");
    beep();
    #endif
}

In this example, when the macro DEBUG is defined, the debugging message "Going Left" will be printed and the board will beep each time the code inserted by GO_LEFT is executed. If the macro is not defined, the preprocessor will not insert the code producing the message and beep. Each #ifdef must be follwed by an #endif at the end of the code which is to be conditionally compiled. The macro name to be checked can be any valid macro name, and #ifdef blocks may be nested.

The counterpart to #ifdef is #ifndef, which causes the program to test to see if the macro has not been defined. It is needed in case the macro definition might or might not already be in a file that has been included. It is an error to try to define a macro that is already defined.

Macros can be conditionally defined.

The #if, #else, and #elif directives are also available, but are outside the scope of this document. Refer to a C reference manual for how to use them.

The C Math Library

One of the standard C libraries included by KISS is the math library, which contains an extensive collection of math routines. The ones below are commonly used for robotics. For more information about what math functions are available, consult your C reference.

atan    [Category: Math]
Format: double atan(double angle);
Returns the arc tangent of the angle. Angle is specified in radians; the result is in radians.
cos   [Category: Math]
Format: double cos(double angle);
Returns cosine of angle. Angle is specified in radians; result is in radians.
exp   [Category: Math]
Format: double exp(double num);
Returns e to the num power.
exp10   [Category: Math]
Format: double exp10(double num);
Returns 10 to the num power.
log   [Category: Math]
Format: double log(double num);
Returns the natural logarithm of num.
log10   [Category: Math]
Format: double log10(double num);
Returns the logarithm of num to the base10.
random   [Category: Math]
Format: int random(int m);
Returns a random integer between 0 and some very large number.
sin   [Category: Math]
Format: double sin(double angle);
Returns the sine of angle. angle is specified in radians; result is in radians.
sqrt    [Category: Math]
Format: double sqrt(double num);
Returns the square root of num.
tan   [Category: Math]
Format: double tan(double angle);
Returns the tangent of angle. angle is specified in radians; result is in radians.

The KIPR Link Library File

Library files provide standard C functions for interfacing with hardware on the robot controller board. These functions are written either in C or as assembly language drivers. Library files provide functions to do things like control motors and input sensors values.

KISS automatically has a selection of library files included every time it invokes the C compiler.

For convenience, a description of some of the more commonly used KIPR Link specific library functions follows.

Commonly Used KIPR Link Library Functions

digital(<port#>);
    /* returns 0 if the switch attached to the port is open and
       returns 1 if the switch is closed.  Digital ports are numbered
       8-15.  Typically used for bumpers or limit switches. */

analog(<port#>);
    /* returns the analog value of the port (a value in the range 0-255).
       Analog ports are numbered 0-7. Light sensors and range sensors are
       examples of sensors you would use in analog ports. */

msleep(<int_msecs>);
      /* waits specified number of milliseconds */

beep();
    /* causes a beep sound */

printf(<string>, <arg1>, <arg2>, ... );
    /* prints <string>.  If the string contains % codes then the <args>
       after the string will be printed in place of the % codes in the
       format specified by the code. %d prints a decimal number. %f
       prints a floating point number. %c prints a character, %x or
       %X prints an integer in hexadecimal. */

mav(<motor_#>, <vel>)
    /* controls the motors. <motor_#> is an integer between 0 and 3.
       <vel> is an integer between -1000 and 1000 where 0
       means the motor is off and negative numbers run the motor in the
       reverse direction */

fd(<motor_#>);
    /* turns on the motor specified (direction is determined by plug
       orientation */

bk(<motor_#>);
    /* turns on the motor specified in the opposite direction from fd */

motor(<motor_#>, <motor_power>);
    /* turns on the motor specified at the power level specified */

off(<motor_#>);
    /* turns off the motor specified */

ao();
    /* turns all motor ports off */

KIPR Link Library Functions

(alphabetic order)

void get_pid_gains(int motor, short *p, short *i, short *d, short *pd, short *id, short *dd); void set_analog_pullup(int port, int pullup); void set_digital_pullup(int port, int pullup);
a_button    [Category: Sensors]
Format: int a_button();
Reads the value (0 or 1) of the A button.
a_button_clicked    [Category: Sensors]
Format: int a_button_clicked();
Gets the A button's state (pressed or not pressed). If pressed, blocks until released. Returns 1 for pressed, 0 for not pressed. The construction
while (a_button()==0) {
while (a_button()==1); ...} //debounce A button

is equivalent to
while (a_button_clicked()==0) {...}
accel_x    [Category: Sensors]
Format: int accel_x();
Returns the value of the accelerometer in its x direction relative to the horizontal plane of the Link.
accel_y    [Category: Sensors]
Format: int accel_y();
Returns the value of the accelerometer in its y direction relative to the horizontal plane of the Link.
accel_z    [Category: Sensors]
Format: int accel_z();
Returns the value of the accelerometer for its vertical, or z direction, relative to the horizontal plane of the KIPR Link. When the Link is horizontal it is calibrated to have a value corresponding to the gravitational constant G (your acceleration to towards the center of the Earth to keep you from flying off of the planet).
alloff   [Category: Motors]
Format: void  alloff();
Turns off all motors. ao is a short form for alloff.
analog    [Category: Sensors]
Format: int analog(int p);
Returns the value of the sensor installed at the port numbered p. The result is an integer between 0 and 255. The function can be used with analog ports 0 through 7.
analog10    [Category: Sensors]
Format: int analog10(int p);
10-bit version of the analog function. The returned value is in the range 0 to 1023 rather than 0 to 255.
any_button   [Category: Sensors]
Format: int  any_button()();
Returns 1 if any button (A,B,C,X,Y,Z,Side) is pressed.
ao    [Category: Motors]
Format: void ao();
Turns off all motors.
b_button    [Category: Sensors]
Format: int b_button();
Reads the value (0 or 1) of the B button.
b_button_clicked    [Category: Sensors]
Format: int b_button_clicked();
Gets the B button's state (pressed or not pressed). If pressed, blocks until released. Returns 1 for pressed, 0 for not pressed. The construction
while (b_button()==0) {
while (b_button()==1); ...} //debounce B button

is equivalent to
while (b_button_clicked()==0) {...}
beep    [Category: Output]
Format: void beep();
Produces a tone. Returns when the tone is finished.
bk    [Category: Motors]
Format: void bk(int m);
Turns motor m on full speed in the backward direction.
Example:
bk(1);

block_motor_done  [Category: Motors]
Format: void block_motor_done(int m);
Function does not return until specified motor completes any executing speed or position control moves.
Example:
mrp(0,500,20000L);
block_motor_done(1);

bmd  [Category: Motors]
Format: void bmd(int m);
Function does not return until specified motor completes any executing speed or position control moves.
Example:
mrp(0,500,20000L);
bmd(1);
c_button    [Category: Sensors]
Format: int c_button();
Reads the value (0 or 1) of the C button.
c_button_clicked    [Category: Sensors]
Format: int c_button_clicked();
Gets the C button's state (pressed or not pressed). If pressed, blocks until released. Returns 1 for pressed, 0 for not pressed. The construction
while (c_button()==0) {
while (c_button()==1); ...} //debounce C button

is equivalent to
while (c_button_clicked()==0) {...}
console_clear   [Category: Output]
Format: void console_clear();
Clear the Link print buffer. See also display_clear.
display_clear   [Category: Output]
Format: void display_clear();
Clear the Link display for display_printf. See also console_clear.
display_printf   [Category: Output]
Format: void display_printf(int col, int row, char s[], . . .);
Perform a standard printf starting at screen location col, row. (col 0 to 41, row 0 to 9)
clear_motor_position_counter   [Category: Motors]
Format: void clear_motor_position_counter(int motor_nbr);
Reset the position counter for the motor specified to 0.
digital   [Category: Sensors]
Format: int digital(int p);
Returns the value of the sensor in sensor port p, as a true/false value (1 for true and 0 for false). Sensors are expected to be active low, meaning that they are valued at zero volts in the active, or true, state. Thus the library function returns the inverse of the actual reading from the digital hardware: if the reading is zero volts or logic zero, the digital() function will return true. Valid for digital ports 8-15.
disable_servo   [Category: Servos]
Format: void disable_servo(int p);
Disables specified servo port.
disable_servos   [Category: Servos]
Format: void disable_servos();
Disables the servo motor ports (powers down all servo motors).
enable_servo   [Category: Servos]
Format: void enable_servo(int p);
Enables specified servo port.
enable_servos   [Category: Servos]
Format: void enable_servos();
Enables all servo motor ports.
extra_buttons_show   [Category: Sensors]
Format: void extra_buttons_show();
Shows the X, Y, and Z buttons on the Link display. Note: this reduces the display area for printf. See also extra_buttons_hide, get_extra_buttons_visible
extra_buttons_hide   [Category: Sensors]
Format: void extra_buttons_hide();
Hides the X, Y, and Z buttons on the Link display. Note: this is the default display configuration. See also extra_buttons_show, get_extra_buttons_visible
fd   [Category: Motors]
Format: void fd(int m);
Turns motor m on full in the forward direction.
Example:
fd(3);
freeze   [Category: Motors]
Format: void freeze(int m);
Freezes motor m (prevents continued motor rotation, in contrast to off, which allows the motor to "coast").

get_analog_pullup   [Category: Sensors]
Format: int get_analog_pullup(intport);
Returns 1 if the port's pullup resistor is set (the default), and 0 otherwise. See also set_analog_pullup
get_extra_buttons_visible   [Category: Sensors]
Format: int get_extra_buttons_visible();
Returns 1 if the X, Y, and Z buttons are visible, 0 if not. See also, extra_buttons_show, extra_buttons_hide
get_motor_done   [Category: Motors]
Format: int get_motor_done(int m);
Returns whether the motor has finished a move with specified position.
get_motor_position_counter   [Category: Motors]
Format: int get_motor_position_counter(int m);
Returns the current motor position value for motor m (a value which is continually being updated for each motor using back EMF; a typical discrimination for a given motor is on the order of 1100 position "ticks" per rotation)
get_pid_gains   [Category: Motors]
Format: int get_pid_gains(int motor, int *p, int *i, int *d, int *pd, int *id, int *dd);
This function is used to obtain the weights of the PID control currently set for the motors. The p, i and d parameters are the numerators for the p, i and d coefficients. The pd, id and dd parameters are their respective denominators. Thus all of the parameters are integers, but the actual coefficients can be floats. If a motor is jerky, the p and d terms should be reduced in size. If a motor lags far behind, they should be increased. The default values are set at firmware install. See also get_pid_gains
get_servo_enabled   [Category: Servos]
Format: int get_servo_enabled(int srv);
Returns 1 if the specified servo port is enabled and 0 otherwise. See also enable_servo, disable_servo.
get_servo_position   [Category: Servos]
Format: int get_servo_position(int srv);
Returns the last position value set for the servo in port srv. The value is in the range 0 to 1023. There are 4 servo ports (0, 1, 2,3). See also set_servo_position.

mav   [Category: Motors]
Format: void mav(int m, int vel);
This function is the same as move_at_velocity
motor   [Category: Motors]   
Format: void motor(int m, int p);
Turns on motor m at scaled PWM duty cycle percentage  p. Power levels range from 100 for full on forward to -100 for full on backward.

move_at_velocity   [Category: Motors]
Format: void move_at_velocity(int m, int vel);
Moves motor m at velocity vel indefinitely. The velocity range is -1000 to 1000 ticks per second.
move_relative_position   [Category: Motors]
Format: void move_relative_position(int m, int speed, int pos);
Moves motor m at velocity vel from its current position curr_pos to curr_pos + pos. The speed range is 0 to 1000 ticks per second.
Example:
move_relative_position(1,275,-1100L);
move_to_position   [Category: Motors]
Format: void move_to_position(int m, int speed, int pos);
Moves motor m at velocity vel from its current position curr_pos to pos. The speed range is 0 to 1000. Note that if the motor is already at pos, the motor doesn't move.
mrp   [Category: Motors]
Format: void mrp(int m, int vel, int pos);
This function is the same as move_relative_position.

mtp  [Category: Motors]   
Format: void mtp(int m, int vel, int pos);
This function is the same as move_to_position.
msleep   [Category: Time]
Format: void msleep(int msec);
Waits for an amount of time equal to or greater than msec milliseconds.
Example:
/*wait for 1.5 seconds */ msleep(1500);
off   [Category: Motors]
Format: void off(int m);
Turns off motor m.
Example:
off(1);
power_level   [Category: Sensor]
Format: double power_level();
Returns the current power level in volts.
printf   [Category: Output]
Format: void printf(char s[], . . .);
Prints the contents of the string referenced by s to the cursor position on the screen.
See the manual above for more details.
run_for   [Category: Processes]
Format: void run_for(double sec, void <function_name>);
This function takes a function and runs it for a certain amount of time in seconds. run_for will return within 1 second of your function exiting, if it exits before the specified time. The variable sec denotes how many seconds to run the given function.
seconds   [Category: Time]
Format: double seconds();
Returns the count of system time in seconds, as a floating point number. Resolution is one millisecond.
set_a_button_text   [Category: Sensors]
Format: void set_a_button_text(char txt[]);
This function sets the text displayed on the A button to be the text string specified rather than 'A'.
set_analog_pullup   [Category: Sensors]
Format: void set_analog_pullup(int port,int pullupTF);
Analog ports provides a pullup resistor for sensors that don't have an integrated pullup resistor which can be turned off for sensors that set their own pullup value (the "ET" optical range finder is such a sensor). For example, set_analog_pullup(3,0); configures analog port 3 to be "floating" (no pullup resistor) whereas set_analog_pullup(3,1); configures port 3 as pullup (enables the pullup resistor)
set_b_button_text   [Category: Sensors]
Format: void set_b_button_text(char txt[]);
This function sets the text displayed on the B button to be the text string specified rather than 'B'.
set_c_button_text   [Category: Sensors]
Format: void set_c_button_text(char txt[]);
This function sets the text displayed on the C button to be the text string specified rather than 'C'.
set_digital_output   [Category: Output]
Format: void set_digital_output(int port, int inout);
Digital ports on the KIPR Link can be configured for either input or output. By default digital ports are set for input. The statement set_digital_output(9,1) will configure digital port 9 for output. The port parameter must be in the range of values 8-15.
set_digital_pullup   [Category: Sensors]
Format: void set_digital_pullup(int port,int pullupTF);
Digital ports provides a pullup resistor for sensors that don't have an integrated pullup resistor which can be turned off for sensors that set their own pullup value (there aren't any digital sensors of this type used for Botball). For example, set_digital_pullup(9,0); configures digital port 9 to be "floating" (no pullup resistor) whereas set_digital_pullup(9,1); configures port 9 as pullup (enables the pullup resistor)
set_digital_value   [Category: Output]
Format: void set_digital_value(int port, int value);
Digital ports on the KIPR Link can be configured for either input or output. For a port configured for output, this function is used to set its value to either 0 (low) or 1 (high). The port parameter must be in the range of values 8-15.
set_pid_gains   [Category: Motors]
Format: int set_pid_gains(int motor, int p, int i, int d, int pd, int id, int dd);
This function is used to adjust the weights of the PID control for the motors. The p, i and d parameters are the numerators for the p, i and d coefficients. The pd, id and dd parameters are their respective denominators. Thus all of the parameters are integers, but the actual coefficients can be floats. If a motor is jerky, the p and d terms should be reduced in size. If a motor lags far behind, they should be increased. The default values are set at firmware install.
set_servo_position   [Category: Servos]
Format: int set_servo_position(int srv, int pos);
Sets the position value of the servo in port srv. The value of pos must be in the range 0 to 2047. There are 4 servo ports (0, 1, 2, 3).
set_x_button_text   [Category: Sensors]
Format: void set_x_button_text(char txt[]);
This function sets the text displayed on the X button to be the text string specified rather than 'X'. See also extra_buttons_hide(), get_extra_buttons_visible();
set_y_button_text   [Category: Sensors]
Format: void set_y_button_text(char txt[]);
This function sets the text displayed on the Y button to be the text string specified rather than 'Y'. See also extra_buttons_hide(), get_extra_buttons_visible();
set_z_button_text   [Category: Sensors]
Format: void set_z_button_text(char txt[]);
This function sets the text displayed on the Z button to be the text string specified rather than 'Z'. See also extra_buttons_hide(), get_extra_buttons_visible();

setpwm   [Category: Motors]
Format: int setpwm(int m, int dutycycle);
Runs motor m at duty cycle dutycycle (values-100 to 100)
side_button (or black_button)   [Category: Sensors]
Format: int side_button();
Reads the value (0 or 1) of the (physical) side button on the KIPR Link.
side_button_clicked    [Category: Sensors]
Format: int side_button_clicked();
Gets the Side button's state (pressed or not pressed). If pressed, blocks until released. Returns 1 for pressed, 0 for not pressed. The construction
while (side_button()==0) {
while (side_button()==1); ...} //debounce Side button

is equivalent to
while (side_button_clicked()==0) {...}
thread_create   [Category: Threads]
Format: thread thread_create(<function name>);
The thread_create function is used to create a thread for running a function in parallel to main. Note that the return value of thread_create has the special data type thread, which should be assigned to a variable of type thread so it remains available for running the function in the thread (via thread_start). The the thread will remain active until the function finishes or the thread is destroyed (via thread_destroy). If the thread hasn't been destroyed, it can be started again; otherwise, a new thread has to be created for the function.
thread_destroy   [Category: Threads]
Format: void thread_destroy(thread id);
The thread_destroy function is used to destroy threads running functions in parallel to main. A thread is destroyed by passing its thread ID number to thread_destroy. The following code shows the main process creating a check_sensor thread, and then destroying it one second later:
int main()
{
    thread tid;
    tid = thread_create(check_sensor);
    thread_start(tid);
    msleep(1000);
    thread_destroy(tpid);
}

thread_start   [Category: Threads]
Format: void thread_start(<thread id >);
The thread_start function is used to start a thread created for a function, which then runs in parallel with other active threads. The system keeps track of each thread by assigning a thread ID value to it. thread_create returns the thread ID value when the thread for running a function is created. The thread is active until the function finishes or until it is terminated by thread_destroy.
thread_wait   [Category: Threads]
Format: void thread_wait(<thread id>);
The thread_wait function is used to wait for a thread that has been started by thread_start to finish where thread id is the thread ID returned by thread_create when the thread was first created.
x_button   [Category: Sensors]
Format: int x_button();
Reads the value (0 or 1) of the X button. This button is an extra button. Use extra_buttons_show() to show the X, Y, and Z buttons. See also extra_buttons_hide(), get_extra_buttons_visible();
x_button_clicked    [Category: Sensors]
Format: int x_button_clicked();
Gets the X button's state (pressed or not pressed). If pressed, blocks until released. Returns 1 for pressed, 0 for not pressed. The construction
while (x_button()==0) {
while (x_button()==1); ...} //debounce X button

is equivalent to
while (x_button_clicked()==0) {...}
This button is an extra button. Use extra_buttons_show() to show the X, Y, and Z buttons. See also extra_buttons_hide(), get_extra_buttons_visible();
y_button   [Category: Sensors]
Format: int y_button();
Reads the value (0 or 1) of the move Y button. This button is an extra button. Use extra_buttons_show() to show the X, Y, and Z buttons. See also extra_buttons_hide(), get_extra_buttons_visible();
y_button_clicked    [Category: Sensors]
Format: int y_button_clicked();
Gets the Y button's state (pressed or not pressed). If pressed, blocks until released. Returns 1 for pressed, 0 for not pressed. The construction
while (y_button()==0) {
while (y_button()==1); ...} //debounce Y button

is equivalent to
while (y_button_clicked()==0) {...}
This button is an extra button. Use extra_buttons_show() to show the X, Y, and Z buttons. See also extra_buttons_hide(), get_extra_buttons_visible();
z_button   [Category: Sensors]
Format: int z_button();
Reads the value (0 or 1) of the move up button. This button is an extra button. Use extra_buttons_show() to show the X, Y, and Z buttons. See also extra_buttons_hide(), get_extra_buttons_visible();
z_button_clicked    [Category: Sensors]
Format: int z_button_clicked();
Gets the Z button's state (pressed or not pressed). If pressed, blocks until released. Returns 1 for pressed, 0 for not pressed. The construction
while (z_button()==0) {
while (z_button()==1); ...} //debounce Z button

is equivalent to
while (z_button_clicked()==0) {...}
This button is an extra button. Use extra_buttons_show() to show the X, Y, and Z buttons. See also extra_buttons_hide(), get_extra_buttons_visible();

Create Library Functions

The Create library is automatically loaded whenever the KIPR Link is chosen as the target. The functions which update sensor data, and the connection functions return the requested information if they are successful and return a number greater than100,000 if there is some error. If an error is returned the error message is 100,000 + the Create Serial Interface Packet Number. For example a code of 100,007 indicates an error when requesting bumper or wheel drop sensor status. The functions starting get_create_ all take a single floating point argument which indicates that the sensor data should be updated if it is older than the argument. In other words, calling get_create_lbump(0.1) indicates that if the sensor data is less than 1/10th of a seconds old, then the cached value will be returned, but if it is older then a new value from the Create will be returned and cached. Calling with an argument of 0 will force a new value to be retrieved from the Create. Note that there is significant overhead in talking with the Create and so the lag times passed to these functions should not be smaller than needed. Values less than 0.05 should be avoided and larger times should be used for the angle and distance functions.

The movement function, with the exception of the script and block functions are all non-blocking. Movement functions (with the exception of create_stop()) only are sent to the Create if they represent a change from the previous movement command. For this reason, movement commands may be placed in tight loops without concern of overwhelming the serial connection. The Create's trajectory will continue until a different movement command is given. The script commands will execute without blocking and will finish when the goal is reached. The blocking spin function will not return until the goal has been reached.

The Create may also be used to play MIDI music. Up to sixteen 16 note songs may be loaded into the Create from the global variable matrix gc_song_array. See the Create Open Interface manual for details on note and duration codes.

create_connect    [Category: Create Function]

Format: int create_connect();
First step for connecting KIPR Link to Create. Returns 0 if sucessful and a negative number if not. This function puts the Create in the create_safe mode.

create_disconnect    [Category: Create Function]

Format: void create_disconnect();
restores the Create to power on configuration (which will also shut off any running motors).

create_start    [Category: Create Function]

Format: void create_start();
Puts Create into active mode (with motors)

create_passive    [Category: Create Function]

Format: void create_passive();
Puts Create into passive mode (no motors)

create_safe    [Category: Create Function]

Format: void create_safe();
Create will execute all commands, but will disconnect and stop if drop or cliff sensors fire.

create_full    [Category: Create Function]

Format: void create_full();
Create will move however you tell it -- even if that is a bad thing. In particular, the Create will not stop and disconnect, even if it is picked up or the cliff sensors fire.

create_spot    [Category: Create Function]

Format: void create_spot();
Simulates a Roomba doing a spot clean

create_cover    [Category: Create Function]

Format: void create_cover();
Simulates a Roomba covering a room

create_demo    [Category: Create Function]

Format: void create_demo(int d);
Runs built in demos (see Create OI)

create_cover_dock    [Category: Create Function]

Format: void create_cover_dock();
Create roams around until it sees an IR dock and then attmpts to dock

get_create_mode    [Category: Create Function]

Format: int get_create_mode(double lag);
Returns the Create's mode (0 off; 1 passive; 2 safe; 3 full). Data has been gathered within lag seconds.

get_create_lbump    [Category: Create Sensor Function]

Format: int get_create_lbump(double lag);
returns 1 if left bumper is pressed, 0 otherwise. Data has been gathered within lag seconds.

get_create_rbump    [Category: Create Sensor Function]

Format: int get_create_rbump(double lag);
returns 1 if right bumper is pressed, 0 otherwise. Data has been gathered within lag seconds.

get_create_lwdrop    [Category: Create Sensor Function]

Format: int get_create_lwdrop(double lag);
returns 1 if left wheel has dropped, 0 otherwise. Data has been gathered within lag seconds.

get_create_cwdrop    [Category: Create Sensor Function]

Format: int get_create_cwdrop(double lag);
returns 1 if caster wheel has dropped, 0 otherwise. Data has been gathered within lag seconds.

get_create_rwdrop    [Category: Create Sensor Function]

Format: int get_create_rlwdrop(double lag);
returns 1 if right wheel has dropped, 0 otherwise. Data has been gathered within lag seconds.

get_create_wall    [Category: Create Sensor Function]

Format: int get_create_wall(double lag);
returns 1 if wall is detected by right facing sensor, 0 otherwise. Data has been gathered within lag seconds.

get_create_lcliff    [Category: Create Sensor Function]

Format: int get_create_lcliff(double lag);
returns 1 if left cliff sensor is over black or a cliff, 0 otherwise. Data has been gathered within lag seconds.

get_create_lfcliff    [Category: Create Sensor Function]

Format: int get_create_lfcliff(double lag);
returns 1 if left front cliff sensor is over black or a cliff, 0 otherwise. Data has been gathered within lag seconds.

get_create_rfcliff    [Category: Create Sensor Function]

Format: int get_create_rfcliff(double lag);
returns 1 if right frontcliff sensor is over black or a cliff, 0 otherwise. Data has been gathered within lag seconds.

get_create_rcliff    [Category: Create Sensor Function]

Format: int get_create_rcliff(double lag);
returns 1 if right cliff sensor is over black or a cliff, 0 otherwise. Data has been gathered within lag seconds.

get_create_vwall    [Category: Create Sensor Function]

Format: int get_create_vwall(double lag);
returns 1 if a virtual wall beacon is detected, 0 otherwise. Data has been gathered within lag seconds.

get_create_overcurrents    [Category: Create Sensor Function]

Format: int get_create_overcurrents(double lag);
returns the overcurrent status byte where 16's bit indicates overcurrent in left wheel; 8's bit in right wheel, 4's bit is LD2, 2's bit is LD0 and 1's bit is LD1. Data has been gathered within lag seconds.

get_create_infrared    [Category: Create Sensor Function]

Format: int get_create_infrared(double lag);
returns the byte detected from the remote control, 255 if no byte has been detected. Data has been gathered within lag seconds.

get_create_advance_button    [Category: Create Sensor Function]

Format: int get_create_advance_button(double lag);
returns 1 if advance button is being pressed, 0 otherwise. Data has been gathered within lag seconds.

get_create_play_button    [Category: Create Sensor Function]

Format: int get_create_play_button(double lag);
returns 1 if play button is being pressed, 0 otherwise. Data has been gathered within lag seconds.

get_create_distance    [Category: Create Sensor Function]

Format: int get_create_distance(double lag);
returns the accumulated distance the Create has traveled since it was turned on or the distance was set. Moving backwards reduces this value. The distance is in millimeters. The value is truncated to the nearest millimeter every time this function is updated so having the lag time be too small will cause an artificially small value. Suggested lag values are no smaller than 5/speed where speed is the Create's speed in mm/sec. Data has been gathered within lag seconds.

set_create_distance    [Category: Create Sensor Function]

Format: void set_create_distance(int dist);
Sets the current value that will be returned by get_create_distance to the value dist.

get_create_normalized_angle    [Category: Create Sensor Function]

Format: int get_create_normalized_angle(double lag);
returns the accumulated angle the Create has turned since it was turned on or the distance was set -- normalized to the range 0 to 359 degrees. Turning CCW increases this value and CW decreases the value. The value is truncated to the nearest degree every time this function is updated so having the lag time be too small will cause an artificially small value. Suggested lag values are no smaller than 10/(difference between left and right wheel speeds). Data has been gathered within lag seconds.

get_create_total_angle    [Category: Create Sensor Function]

Format: int get_create_total_angle(double lag);
returns the accumulated angle the Create has turned since it was turned on or the distance was set. Turning CCW increases this value and CW decreases the value. The value is truncated to the nearest degree every time this function is updated so having the lag time be too small will cause an artificially small value. Suggested lag values are no smaller than 10/(difference between left and right wheel speeds). Data has been gathered within lag seconds.

set_create_normalized_angle    [Category: Create Sensor Function]

Format: void set_create_normalized_angle(int angle);
Sets the current value that will be returned by get_create_normalized_angle to the value angle.

set_create_total_angle    [Category: Create Sensor Function]

Format: void set_create_total_angle(int angle);
Sets the current value that will be returned by get_create_total_angle to the value angle.

get_create_battery_charging_state    [Category: Create Sensor Function]

Format: int get_create_charging_state(double lag);
0-not charging; 1-recondition charging; 2-full charging; 3-trickle charging; 4-waiting; 5-charge fault. Data has been gathered within lag seconds.

get_create_battery_voltage    [Category: Create Sensor Function]

Format: int get_create_battery_voltage(double lag);
returns the battery voltage in mV. Data has been gathered within lag seconds.

get_create_battery_current    [Category: Create Sensor Function]

Format: int get_create_battery_current(double lag);
returns the current flow in mA. Data has been gathered within lag seconds.

get_create_battery_temp    [Category: Create Sensor Function]

Format: int get_create_battery_temp(double lag);
returns the battery temperature in degrees C. Data has been gathered within lag seconds.

get_create_battery_charge    [Category: Create Sensor Function]

Format: int get_create_battery_charge(double lag);
returns the battery charge in mAh. Data has been gathered within lag seconds.

get_create_battery_capacity    [Category: Create Sensor Function]

Format: int get_create_battery_capacity(double lag);
returns the battery capacity in mAh. Data has been gathered within lag seconds.

get_create_wall_amt    [Category: Create Sensor Function]

Format: int get_create_wall_amt(double lag);
returns 12 bit analog value from wall sensor. Data has been gathered within lag seconds.

get_create_lcliff_amt    [Category: Create Sensor Function]

Format: int get_create_lcliff_amt(double lag);
returns 12 bit analog value from left cliff sensor. Data has been gathered within lag seconds.

get_create_lfcliff_amt    [Category: Create Sensor Function]

Format: int get_create_lfcliff_amt(double lag);
returns 12 bit analog value from left front cliff sensor. Data has been gathered within lag seconds.

get_create_rfcliff_amt    [Category: Create Sensor Function]

Format: int get_create_rfcliff_amt(double lag);
returns 12 bit analog value from right frontcliff sensor. Data has been gathered within lag seconds.

get_create_rcliff_amt    [Category: Create Sensor Function]

Format: int get_create_rcliff_amt(double lag);
returns 12 bit analog value from right cliff sensor. Data has been gathered within lag seconds.

get_create_bay_DI    [Category: Create Sensor Function]

Format: int get_create_bay_DI(float lag);
returns byte containing all digital sensors from the cargo bay: 16'bit for pin 15, 8's bit for pin 6, 4's bit for pin 18, 2's bit for pin 5 and 1's bit for pin 17. Data has been gathered within lag seconds.

get_create_bay_AI    [Category: Create Sensor Function]

Format: int get_create_bay_AI(float lag);
returns 10 bit analog value on pin 4 from the cargo bay. Data has been gathered within lag seconds.

get_create_song_number    [Category: Create Sensor Function]

Format: int get_create_song_number(float lag);
returns currently selected song 0-15. Data has been gathered within lag seconds.

get_create_song_playing    [Category: Create Sensor Function]

Format: int get_create_song_playing(float lag);
returns 1 if song is playing, 0 otherwise. Data has been gathered within lag seconds.

get_create_number_of_stream_packets    [Category: Create Sensor Function]

Format: int get_create_number_of_stream_packets(float lag);
if data streaming is being used, it returns the size of the stream. Data has been gathered within lag seconds.

get_create_requested_velocity    [Category: Create Sensor Function]

Format: int get_create_requested_velocity(float lag);
asks Create how fast it was told to be moving -500 to 500mm/s and returns that value. Data has been gathered within lag seconds.

get_create_requested_radius    [Category: Create Sensor Function]

Format: int get_create_requested_radius(double lag);
asks Create the size of its turning radius and returns that value. Data has been gathered within lag seconds.

get_create_requested_right_velocity    [Category: Create Sensor Function]

Format: int get_create_requested_right_velocity(double lag);
asks Create how fast it was told to be moving right wheel and returns that value. Data has been gathered within lag seconds.

get_create_requested_left_velocity    [Category: Create Sensor Function]

Format: int get_create_requested_left_velocity(double lag);
asks Create how fast it was told to be moving left wheel and returns that value. Data has been gathered within lag seconds.

create_stop    [Category: Create Movement Function]

Format: void create_stop();
Stops the drive wheels

create_drive    [Category: Create Movement Function]

Format: void create_drive(int speed, int radius);
Drives in an arc (see below for point turns and straight). Speed range for all commands is 20-500mm/s

create_drive_straight    [Category: Create Movement Function]

Format: void create_drive_straight(int speed);
Drives straight at speed in mm/s

create_spin_CW    [Category: Create Movement Function]

Format: void create_spin_CW(int speed);
spins Clockwise with edge speed of speed in mm/s

create_spin_CCW    [Category: Create Movement Function]

Format: void create_spin_CCW(int speed);
spins Counterclockwise with edge speed of speed in mm/s

create_drive_direct    [Category: Create Movement Function]

Format: void create_drive_direct(int r_speed, int l_speed);
Specifies individual left and right speeds in mm/s

create_advance_led    [Category: Create Function]

Format: void create_advance_led(int on);
Pass 1 to turn on light and 0 to turn it off

create_play_led    [Category: Create Function]

Format: void create_play_led(int on);
Pass 1 to turn on light and 0 to turn it off

create_power_led    [Category: Create Function]

Format: void create_power_led(int color, int brightness);
color 0 is red and 255 green; brightness 0 is off and 255 is full brightness

create_load_song    [Category: Create Function]

Format: void create_load_song(int num);
Picks a song from gc_song_array[16][33]. Each row is a song. First column of each song is number of notes (max is 16). Remaining columns alternate between pitch and duration. See Create OI for details.

create_play_song    [Category: Create Function]

Format: void create_play_song(int num);
Plays any of the songs that have been loaded

KIPR Link Vision Library Functions

camera_close    [Category: Vision]

Format: void camera_close();
Cleanup the current camera instance. See also camera_open, camera_open_device.

camera_load_config    [Category: Vision]

Format: int camera_load_config(char name[]);
Causes the camera_load functions to load a config file on the KIPR Link other than the default config file. You must append .config to the name for this function to locate it. Returns 1 on success, 0 on failure. See also camera_open, camera_open_device.

camera_open    [Category: Vision]

Format: int camera_open(int res_numb);
Opens the KIPR Link's default channel configuration. The default configuration is selected from among the channel configurations defined on the KIPR Link using its settings >> channels menu. A resolution of one of LOW_RES, MED_RES, HIGH_RES needs to be specified. Returns 1 on success, 0 on failure. See also camera_open_device, camera_close.

camera_open_device    [Category: Vision]

Format: int camera_open_device(int number, int res_numb);
If more than 1 camera is plugged in, 0 is the first camera, 1 is the second camera, etc. Only 1 camera at a time can be used, and the default configuration is selected. A resolution of one of LOW_RES, MED_RES, HIGH_RES needs to be specified. Returns 1 on success, 0 on failure. See also camera_open, camera_close.

camera_update    [Category: Vision]

Format: int camera_update();
Pulls a new image from the camera for processing. Returns 1 on success, 0 on failure.

get_channel_count    [Category: Vision]

Format: int get_channel_count()();
Returns the number of channels in the current configuration. See also get_object_count.

get_code_num    [Category: Vision]

Format: int get_code_num(int channel, int object);
Returns the data associated with the given channel and object as an integer. If the given channel or object doesn't exist, -1 is returned. See also get_object_data.

get_object_area    [Category: Vision]

Format: int get_object_area(int channel, int object);
Returns the object's bounding box area. -1 is returned if the channel or object doesn't exist.

get_object_bbox    [Category: Vision]

Format: rectangle get_object_bbox(int channel, int object);
Returns the bounding box of the given object on the given channel as a rectangle data type. For example,

rectangle mybox;
mybox = get_object_bbox(0,2);
printf("x coord %d y coord %d\n", mybox.x, mybox.y);


displays the x and y coordinates of bounding box 2 for channel 0.

get_object_center    [Category: Vision]

Format: point2 get_object_center(int channel, int object);
Returns The (x, y) center of the given object on the given channel as a point2 data type. For example,

point2 mcenter;
mcenter = get_object_center(0,2);
printf("x center coord %d y center coord %d\n", mcenter.x, mcenter.y);


displays the x and y coordinates of center point of box 2 for channel 0.

get_object_centroid    [Category: Vision]

Format: int get_object_centroid(int channel, int object);
Returns The (x, y) coordinates of the centroid of the given object on the given color channel as a point2 data type (the centroid is the center of mass for the pixels of the specified color). For example,

point2 mcenter;
mcentroid = get_object_centroid(0,2);
printf("x centroid coord %d y centroid coord %d\n", mcentroid.x, mcentroid.y);


displays the x and y coordinates of centroid of box 2 for color channel 0.

get_object_confidence    [Category: Vision]

Format: double get_object_confidence(int channel, int object);
Returns the confidence, between 0.0 and 1.0, that the given object on the given channel is significant. If the channel or object doesn't exist, 0.0 is returned.

get_object_count    [Category: Vision]

Format: int get_object_count(int channel);
Returns the number of objects being "seen" by the specified channel. Objects are sorted by area, largest first. Returns -1 if channel doesn't exist. See also get_channel_count.

get_object_data    [Category: Vision]

Format: char *get_object_data(int channel, int object);
Returns the sequence of character data associated with a given object on a QR channel. If there is no data associated, 0 is returned. The data is not guaranteed to be null terminated, but can be accessed using array notation; for example,

get_object_data(0,0)[0], get_object_data(0,0)[1], etc.

camera_update(); will invalidate the pointer returned by get_object_data. See also get_object_data_length.

get_object_data_length    [Category: Vision]

Format: int get_object_data_length(int channel, int object);
Returns the number of characters associated with the QR code on a QR channel. If there is no data associated, 0 is returned. If the channel or object is invalid, 0 is returned. See also get_object_data.

Categorized Function List

Botball

  • void run_for(double delay, void (*funcname))
  • void shut_down_in(double delay)
  • int target_cha_in_chb(int cha, int chb, int *x, int *y)
  • void wait_for_light(int light_port_)

Create

  • int create_connect();
  • void create_disconnect();
  • void create_start();
  • void create_passive();
  • void create_safe();
  • void create_full();
  • void create_spot();
  • void create_cover();
  • void create_demo(int d);
  • void create_cover_dock();
  • int get_create_mode();
  • int get_create_lbump();
  • int get_create_rbump();
  • int get_create_lwdrop();
  • int get_create_cwdrop();
  • int get_create_rwdrop();
  • int get_create_wall();
  • int get_create_lcliff();
  • int get_create_lfcliff();
  • int get_create_rfcliff();
  • int get_create_rcliff();
  • int get_create_vwall();
  • int get_create_overcurrents();
  • int get_create_infrared();
  • int get_create_advance_button();
  • int get_create_play_button();
  • int get_create_normalized_angle();
  • void set_create_normalized_angle(int angle);
  • int get_create_total_angle();
  • void set_create_total_angle(int angle);
  • int get_create_distance();
  • void set_create_distance(int dist);
  • int get_create_battery_charging_state();
  • int get_create_battery_voltage();
  • int get_create_battery_current();
  • int get_create_battery_temp();
  • int get_create_battery_charge();
  • int get_create_battery_capacity();
  • int get_create_wall_amt();
  • int get_create_lcliff_amt();
  • int get_create_lfcliff_amt();
  • int get_create_rfcliff_amt();
  • int get_create_rcliff_amt();
  • int get_create_bay_DI();
  • int get_create_bay_AI();
  • int get_create_song_number();
  • int get_create_song_playing();
  • int get_create_number_of_stream_packets();
  • int get_create_requested_velocity();
  • int get_create_requested_radius();
  • int get_create_requested__right_velocity();
  • int get_create_requested_left_velocity();
  • void create_stop();
  • void create_drive(int speed, int radius);
  • void create_drive_straight(int speed);
  • void create_spin_CW(int speed);
  • void create_spin_CCW(int speed);
  • void create_drive_direct(int r_speed, int l_speed);
  • void create_advance_led(int on);
  • void create_play_led(int on);
  • void create_power_led(int color, int brightness);
  • void create_load_song(int num);
  • void create_play_song(int num);

Math

  • double atan(double angle);
  • double cos(double angle);
  • double exp10(double num);
  • double exp(double num);
  • int log10(double num);
  • double log(double num);
  • int random(int m);
  • double sin(double angle);
  • double sqrt(double num);
  • double tan(double angle);

Motors

  • void alloff();
  • void ao();
  • void bk(int m);
  • void block_motor_done(int m);
  • void bmd(int m);
  • void clear_motor_position_counter(int motor_nbr);
  • void fd(int m);
  • void freeze(int m);
  • int get_motor_done(int m);
  • int get_motor_position_counter(int m);
  • void mav(int m, int vel);
  • void motor(int m, int p);
  • void move_at_velocity(int m, int vel);
  • void move_relative_position(int m, int speed, int pos);
  • void move_to_position(int m, int speed, int pos);
  • void mrp(int m, int vel, int pos);
  • void mtp(int m, int vel, int pos);
  • void off(int m);
  • int set_pid_gains(int motor, int p, int i, int d, int pd, int id, int dd);
  • int setpwm(int m, int dutycycle);

Output

  • void beep();
  • void display_clear();
  • void display_printf(int col, int row, char s[], . . .);
  • void printf(char s[], . . .);
  • void set_digital_output(int port, int inout);
  • void set_digital_value(int port, int value);

Processes

  • thread thread_create(<function_name>);
  • void thread_destroy(<thread id>);
  • void thread_start(<thread id>);
  • void thread_join(<thread id>);
  • void run_for(double sec, void <function_name>);

Sensors

  • int a_button();
  • int analog(int p);
  • int analog10(int p);
  • int b_button();
  • int side_button();
  • int digital(int p);
  • double power_level();
  • void set_each_analog_state(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7);
  • void set_analog_pullup(int port, int pullupTF);

Servos

  • void disable_servos();
  • void enable_servos();
  • int get_servo_position(int srv);
  • int set_servo_position(int srv, int pos);

Time

  • void msleep(int msec);
  • double seconds();

Vision

  • void camera_close();
  • int camera_load_config(char name[]); [name is config name from the Link with .config appended]
  • int camera_open(int res_numb); [res_numb is 1 of LOW_RES, MED_RES, HIGH_RES]
  • int camera_open_device(int number, int res_numb);
  • int camera_update();
  • int get_channel_count();
  • int get_code_num(int channel, int object);
  • int get_object_area(int channel, int object);
  • rectangle get_object_bbox(int channel, int object);
  • point2 get_object_center(int channel, int object);
  • point2 get_object_centroid(int channel, int object);
  • double get_object_confidence(int channel, int object);
  • int get_object_count(int channel);
  • char *get_object_data(int channel, int object);
  • int get_object_data_length(int channel, int object);

Botball

Several functions have been created to assist programmers in creating programs that meet the basic Botball requirements of having robots wait until the starting lights come on and have their programs shut down after a specified amount of time. A typical Botball program will call the function

wait_for_light(<port_num>);

following any other set up routines it might be using. This function walks the robot operator through the light calibration routine, reports if the calibration was sucessful, and if it was, blocks until the light is turned on (if not, the process repeats after a brief pause). Normally this is immediately followed by a call to the Botball function

shut_down_in(<time>);

which will shutdown all motors and the Create once the specified time has expired, then terminate the program. If instead of completely killing the program you wish to do some activity for a specified time and then move on to other things, the function

run_for(<time, <func_name>);

will execute the requested function for the specified time and then halt that function if it has not already exited, allowing the statements following the run_for statement to be executed (such having servo motors maintain position).

The function

target_cha_in_chb(<cha>, <chb>, <*x>, <*y>);

uses the vision system to look for a color target where the color described in the color channel a is completely surrounded by the color described by the color channel b. The addresses of to two integer variables, x & y, are also passed. If a suitable target is found in the current frame (this function does NOT perform a track_update() call) then the function returns 1 and the contents of the two variables x and y are changed to match the image pixel location of the centroid of the color blob associated with the inside of the target. If no target with the right colors is in view, then 0 is returned and x and y are not modified. If more than one target is in view, the one with the larger inner blob (as seen by the camera) is the one whose coordinates are returned. An example of use, where the inner color is on channel 3 and the outer on 2, might be:

{int x,y; if (target_cha_in_chb(3,2,&x,&y)==1)printf("Target found at (%d,%d)\n",x,y);}

The library functions for Botball are:

run_for(<time>, <function_name>);
    /* Executes the function <function_name>
       until it completes or the time <time> has expired. */

shut_down_in(<time>);
    /* Returns immediately but starts a process
    that at the end of <time> will kill the program and
    turn off all motors and issue a stop command to the Create. */

target_cha_in_chb(<cha>, <chb>, <*x>, <*y>);
    /* Looks for a target: a color surrounded by
    another color where the channel number (0-3) for the inner color
    is cha and the surrounding color channel is chb.  If the target is
    found then the function returns 1, otherwise 0.  If a target is
    found then the contents of the variables pointed to by x and y are
    changed. */

wait_for_light(<port>);
    /* Will run the operator through a
    calibration procedure sampling light levels on a sensor plugged
    into port number <port> when the starting light is on
    and off and then blocks until it senses the starting light has
    turned on. */

Threads

The term thread is short for the phrase "thread of execution", and represents a sequence of instructions to be managed by the system as it schedules processimg time among running processes. On a single processor machine, like the KIPR Link, the instructions running in separate threads appear to be operating in parallel. Each thread, once started, will continue until its process finishes or until it is forcibly terminated by another process using the thread_destroy(<thread_id>); statement. Each active thread gets a small amount of time in turn until all of its statements have been executed or it is forcibly terminated. If a thread's process cannot complete all of its statements before its turn is over, it is paused temporarily for the next thread to gets its share of time. This continues until all the active threads have gotten their slice of time and then it all repeats. The Link's processor is fast enough that from the user's viewpoint it appears that all of the active processes are running in parallel.

Functions running in threads can communicate with one another by reading and modifying global variables. The globals can be used as semaphores so that one process can signal another. Process IDs may also be stored in globals so that one process can destroy another one's thread if that is necessary program logic (think in terms of a process that is in an indefinite loop monitoring sensors, so it will never finish).

The library functions for controlling threads are:

thread_create(<function_name>);
    /* thread_create creates a thread for running the specified function <function_name> and returns a value
       of type thread that is the thread ID to be used for running the thread as an independent process */

thread_destroy(<thread_id>);
    /* this will terminate (and remove) the thread specified by <thread_id>
       (and stop its associated process)  */

thread_start(<thread_id>);
    /* this will activate the thread specified by <thread_id>
       and run its associated process  */

thread_wait(<thread_id>);
    /* this will cause the program to wait until the specified <thread_id>
       has finished - this can be used to sychronize two threads */

Sensors

The image below is the front of the KIPR Link where all the sensor, motor, and servo ports can be found.





Light Sensor
(analog)

Infrared "Top Hat" Reflectance Sensor
(analog)

Infrared "E.T." Distance Sensor
(floating analog)

Touch Sensors
(digital)

Infrared "Break Beam" Sensor
(digital)




Analog Slider Sensor
(analog)

Analog Pot Sensor
(analog)

Small Reflectance Sensor
(analog)

Light Sensor (analog)


Infrared "Top Hat" Reflectance Sensor, Small Reflectance Sensor (analog)


Infrared "E.T." Distance Sensor (floating analog)


Touch Sensors (digital)


Infrared "Break Beam" Sensor (digital)


Analog Slider


Analog Pot (potentiometer)